home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Draw Editor / Source / LinkCommands.cpp < prev    next >
Encoding:
Text File  |  1995-12-11  |  17.3 KB  |  593 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ShapeCommands.cpp
  3.  
  4.     Contains:    Link Commands Implementation
  5.  
  6.     Written by:    Mike Halpin
  7.     
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- DrawEditor Includes --
  12.  
  13. #ifndef _LINKCOMMANDS_
  14. #include "LinkCommands.h"
  15. #endif
  16.  
  17. #ifndef _SHAPES_
  18. #include "Shapes.h"
  19. #endif
  20.  
  21. #ifndef _SELECTION_
  22. #include "Selection.h"
  23. #endif
  24.  
  25. #ifndef _DRAWEDITORGLOBALS_
  26. #include "DrawEditorGlobals.h"
  27. #endif
  28.  
  29. #ifndef _DRAWEDITOR_
  30. #include "DrawEditor.h"
  31. #endif
  32.  
  33. #ifndef _DRAWEDITORUTILS_
  34. #include "DrawEditorUtils.h"
  35. #endif
  36.  
  37. #ifndef _LINK_
  38. #include "Link.h"
  39. #endif
  40.  
  41. #ifndef _UTILERRS_
  42. #include "UtilErrs.h"
  43. #endif
  44.  
  45. // -- OpenDoc Includes --
  46.  
  47. #ifndef SOM_ODLinkSpec_xh
  48. #include <LinkSpec.xh>
  49. #endif
  50.  
  51. #ifndef SOM_ODLink_xh
  52. #include <Link.xh>
  53. #endif
  54.  
  55. #ifndef SOM_ODClipboard_xh
  56. #include <Clipbd.xh>
  57. #endif
  58.  
  59. #ifndef SOM_ODDragItemIterator_xh
  60. #include <DgItmIt.xh>
  61. #endif
  62.  
  63. // -- OpenDoc Utilities --
  64.  
  65. #ifndef _ODUTILS_
  66. #include "ODUtils.h"
  67. #endif
  68.  
  69. #ifndef _EXCEPT_
  70. #include "Except.h"
  71. #endif
  72.  
  73. #ifndef _ODDEBUG_
  74. #include "ODDebug.h"
  75. #endif
  76.  
  77. #ifndef _ISOSTR_
  78. #include "ISOStr.h"            // ODISOStrFromCStr
  79. #endif
  80.  
  81. //=============================================================================
  82. // class CPasteLinkCommand
  83. //=============================================================================
  84.  
  85. //---------------------------------------------------------------------------------------
  86. //    CPasteLinkCommand::CPasteLinkCommand
  87. //---------------------------------------------------------------------------------------
  88.  
  89. CPasteLinkCommand::CPasteLinkCommand(    DrawEditor* theEditor, 
  90.                                         CSelection* selection,
  91.                                         ODStorageUnit* contentSU,
  92.                                         ODPasteAsResult& paResult,
  93.                                         ODBoolean defaultIsMerge) :
  94. CCommand(theEditor,  kODTrue, kODTrue, kUndoPasteLinkIndex, kRedoPasteLinkIndex)
  95. {
  96.     fSelection = selection;
  97.     fContentSU = contentSU;
  98.     fPaResult = paResult;
  99.     
  100.     // we're going to 'steal' the kind string in the paResult, which would otherwise just get
  101.     // deleted by the caller, and give it to the link. Clear the field so it won't be deleted by the caller.
  102.     
  103.     paResult.selectedKind = kODNULL;
  104.     
  105.     // we're not going to use the translateKind. Clear the field in our copy
  106.     // and allow the caller to delete the string.
  107.     
  108.     fPaResult.translateKind = kODNULL;
  109.     
  110.     fDefaultIsMerge = defaultIsMerge;
  111.     
  112.     fSubscribeLink = kODNULL;
  113.     
  114.     this->SetActionType(kODBeginAction);
  115.  
  116. }
  117.  
  118. //---------------------------------------------------------------------------------------
  119. //    CPasteLinkCommand::~CPasteLinkCommand
  120. //---------------------------------------------------------------------------------------
  121.  
  122. CPasteLinkCommand::~CPasteLinkCommand()
  123. {
  124. }
  125.  
  126. //---------------------------------------------------------------------------------------
  127. //    CPasteLinkCommand::Commit
  128. //---------------------------------------------------------------------------------------
  129.  
  130. void CPasteLinkCommand::Commit(Environment* ev, ODDoneState state)//Override
  131.  
  132. {
  133.     CCommand::Commit (ev, state);
  134.     
  135.     if (state == kODUndone)
  136.     {
  137.         fSubscribeLink->RemoveShapes(ev, kODTrue);
  138.         delete fSubscribeLink;
  139.     }
  140. }
  141.  
  142. //---------------------------------------------------------------------------------------
  143. //    CPasteLinkCommand::DoCommand
  144. //---------------------------------------------------------------------------------------
  145.  
  146. void CPasteLinkCommand::DoCommand(Environment* ev)
  147. {
  148.     CCommand::DoCommand (ev);
  149.  
  150.     ODLinkSpec* linkSpec = kODNULL;
  151.     ODLink* odLink = kODNULL;
  152.     ODDraft* draft = fDrawEditor->GetDraft(ev);
  153.     ODLinkInfo linkInfo;
  154.     
  155.     // give the selectedKind string to the linkInfo and clear the fPaResult reference.
  156.     // doing before TRY block simplifies CATCH_ALL block
  157.     
  158.     linkInfo.kind = fPaResult.selectedKind;
  159.     fPaResult.selectedKind = kODNULL;    
  160.     
  161.     // Empty the selection
  162.     fSelection->CloseSelection(ev);
  163.     
  164.     ODVolatile(linkSpec);
  165.     ODVolatile(odLink);
  166.     ODVolatile(linkInfo);
  167.  
  168.     linkSpec = draft->CreateLinkSpec(ev, kODNULL, kODNULL);
  169.  
  170.     fContentSU->Focus(ev, kODPropLinkSpec, kODPosUndefined, (ODValueType)kODNULL, 0, kODPosUndefined);
  171.     linkSpec->ReadLinkSpec(ev, fContentSU);
  172.  
  173.     TRY
  174.         // ---- Establish the Link ----
  175.         odLink = draft->AcquireLink(ev, (ODStorageUnitID)0, linkSpec);    // use linkSpec to retrieve the link
  176.         delete linkSpec;
  177.  
  178.     CATCH_ALL
  179.     
  180.         delete linkSpec;
  181.         delete linkInfo.kind;
  182.         this->AbortLink(ev);
  183.         RERAISE;
  184.         
  185.     ENDTRY
  186.                     
  187.     ASSERT_NOT_NULL(odLink);
  188.     
  189.             linkInfo.change = kODUnknownUpdate;    // not yet updated
  190.             GetDateTime(&linkInfo.creationTime);
  191.             linkInfo.changeTime = linkInfo.creationTime;
  192.             linkInfo.autoUpdate = fPaResult.autoUpdateSetting;
  193.             
  194.     // In case of a low-mem failure, we'll be proper and release the ODLink. Once
  195.     // we have a CSubscribeLink, it's going to be responsible for that.
  196.     TRY
  197.         // Create the CSubscribeLink
  198.         fSubscribeLink = new CSubscribeLink(odLink, fSelection, linkInfo, fPaResult, 
  199.                                                 fDefaultIsMerge);
  200.     CATCH_ALL
  201.         odLink->Release(ev);
  202.         this->AbortLink(ev);
  203.         RERAISE;
  204.     ENDTRY
  205.             
  206.     // set up the CSubscribeLink behavior for first update.                                        
  207.     this->SetUpdateParameters();
  208.     
  209.     fSubscribeLink->Subscribe(ev);  
  210. }
  211.  
  212. //---------------------------------------------------------------------------------------
  213. //    CPasteLinkCommand::RedoCommand
  214. //---------------------------------------------------------------------------------------
  215.  
  216. void CPasteLinkCommand::RedoCommand(Environment* ev)//Override
  217.  
  218. {
  219.     CCommand::RedoCommand (ev);
  220.     
  221.     fSubscribeLink->AddToPart(ev);
  222. }
  223.  
  224. //---------------------------------------------------------------------------------------
  225. //    CPasteLinkCommand::UndoCommand
  226. //---------------------------------------------------------------------------------------
  227.  
  228. void CPasteLinkCommand::UndoCommand(Environment* ev)//Override
  229. {
  230.     CCommand::UndoCommand (ev);
  231.     
  232.     fSubscribeLink->RemoveFromPart(ev);
  233. }
  234.  
  235. //---------------------------------------------------------------------------------------
  236. //    CPasteLinkCommand::SetUpdateParameters
  237. //---------------------------------------------------------------------------------------
  238.  
  239. void CPasteLinkCommand::SetUpdateParameters()
  240. {
  241.     // Because a cross document link does not actually complete synchronously, in order that
  242.     // CreateLink at the source document be part of a single undoable transaction, we tag
  243.     // the link so that it will create a CEndPasteLinkCommand to terminate the transaction when 
  244.     // it gets it's first real update.
  245.     
  246.     fSubscribeLink->SetCommand(this);
  247. }
  248.  
  249. //---------------------------------------------------------------------------------------
  250. //    CPasteLinkCommand::CompleteLink
  251. //---------------------------------------------------------------------------------------
  252.  
  253. void CPasteLinkCommand::CompleteLink(Environment* ev)
  254. {
  255.     this->WriteAction(ev, kODEndAction);
  256. }
  257.  
  258. //---------------------------------------------------------------------------------------
  259. //    CPasteLinkCommand::AbortLink
  260. //---------------------------------------------------------------------------------------
  261.  
  262. void CPasteLinkCommand::AbortLink(Environment* ev)
  263. {
  264.     this->AbortCommand(ev);
  265.     fSubscribeLink = kODNULL;
  266. }
  267.  
  268.  
  269.  
  270.  
  271. //=============================================================================
  272. // CDropLinkCommand
  273. //=============================================================================
  274.  
  275. //---------------------------------------------------------------------------------------
  276. //    CDropLinkCommand::CDropLinkCommand
  277. //---------------------------------------------------------------------------------------
  278.  
  279. CDropLinkCommand::CDropLinkCommand(    DrawEditor* theEditor, 
  280.                                         CSelection* selection,
  281.                                         ODStorageUnit* dropSU,
  282.                                         ODPoint dropPoint,
  283.                                         ODPasteAsResult& paResult,
  284.                                         ODBoolean defaultIsMerge) :
  285. CPasteLinkCommand(theEditor, selection, dropSU, paResult, defaultIsMerge)
  286. {
  287.     fDropPoint = dropPoint;
  288.  
  289.     // override behavior of CPasteLinkCommand. Drag initiator handles begin and end actions.
  290.     this->SetActionType(kODSingleAction);
  291. }
  292.  
  293.  
  294. //---------------------------------------------------------------------------------------
  295. //    CDropLinkCommand::~CDropLinkCommand
  296. //---------------------------------------------------------------------------------------
  297.  
  298. CDropLinkCommand::~CDropLinkCommand()
  299. {
  300. }
  301.  
  302.  
  303. //---------------------------------------------------------------------------------------
  304. //    CDropLinkCommand::SetUpdateParameters
  305. //---------------------------------------------------------------------------------------
  306.  
  307. void CDropLinkCommand::SetUpdateParameters()
  308. {
  309.     // As of current recipes, Drag initiator must add begin and end actions.  This means that
  310.     // if this creates a cross document link, then the CreateLink at the source will become a
  311.     // separate undoable transaction rather than part of the same transaction as the drag and drop w/link
  312.     
  313.     CPasteLinkCommand::SetUpdateParameters();
  314.     
  315.     // So the first update goes where the user dropped.
  316.     fSubscribeLink->SetOriginPoint(fDropPoint);
  317. }
  318.  
  319. //---------------------------------------------------------------------------------------
  320. //    CDropLinkCommand::CompleteLink
  321. //---------------------------------------------------------------------------------------
  322.  
  323. void CDropLinkCommand::CompleteLink(Environment* ev)
  324. {
  325.     // Do nothing. Drag initiator writes kODEndAction.
  326. }
  327.  
  328. //---------------------------------------------------------------------------------------
  329. //    CDropLinkCommand::AbortLink
  330. //---------------------------------------------------------------------------------------
  331.  
  332. void CDropLinkCommand::AbortLink(Environment* ev)
  333. {
  334.     fSubscribeLink = kODNULL;
  335. }
  336.  
  337.  
  338.  
  339. //=============================================================================
  340. // class CBreakLinkCommand
  341. //=============================================================================
  342.  
  343. //---------------------------------------------------------------------------------------
  344. //    CBreakLinkCommand::CBreakLinkCommand
  345. //---------------------------------------------------------------------------------------
  346.  
  347. CBreakLinkCommand::CBreakLinkCommand(DrawEditor* theEditor, CSubscribeLink* link):
  348. CCommand(theEditor,  kODTrue, kODTrue, kUndoBreakLinkIndex, kRedoBreakLinkIndex)
  349. {
  350.     fSubscribeLink = link;
  351. }
  352.  
  353.  
  354. //---------------------------------------------------------------------------------------
  355. //    CBreakLinkCommand::~CBreakLinkCommand
  356. //---------------------------------------------------------------------------------------
  357.  
  358. CBreakLinkCommand::~CBreakLinkCommand()
  359. {
  360. }
  361.  
  362. //---------------------------------------------------------------------------------------
  363. //    CBreakLinkCommand::Commit
  364. //---------------------------------------------------------------------------------------
  365.  
  366. void CBreakLinkCommand::Commit(Environment* ev, ODDoneState state)//Override
  367. {
  368.     CCommand::Commit (ev, state);
  369.     
  370.     if (state == kODDone || state == kODRedone)
  371.     {
  372.         delete fSubscribeLink;
  373.     }
  374. }
  375.  
  376.  
  377. //---------------------------------------------------------------------------------------
  378. //    CBreakLinkCommand::DoCommand
  379. //---------------------------------------------------------------------------------------
  380.  
  381. void CBreakLinkCommand::DoCommand(Environment* ev)//Override
  382.  
  383. {
  384.     CCommand::DoCommand (ev);
  385.     fSubscribeLink->Unsubscribe(ev);
  386. }
  387.  
  388.  
  389. //---------------------------------------------------------------------------------------
  390. //    CBreakLinkCommand::RedoCommand
  391. //---------------------------------------------------------------------------------------
  392.  
  393. void CBreakLinkCommand::RedoCommand(Environment* ev)//Override
  394.  
  395. {
  396.     CCommand::RedoCommand (ev);
  397.     fSubscribeLink->Unsubscribe(ev);
  398. }
  399.  
  400.  
  401. //---------------------------------------------------------------------------------------
  402. //    CBreakLinkCommand::UndoCommand
  403. //---------------------------------------------------------------------------------------
  404.  
  405. void CBreakLinkCommand::UndoCommand(Environment* ev)//Override
  406.  
  407. {
  408.     CCommand::UndoCommand (ev);
  409.     fSubscribeLink->Subscribe(ev);
  410. }
  411.  
  412. //=============================================================================
  413. // class CBreakLinkSourceCommand
  414. //=============================================================================
  415.  
  416. //---------------------------------------------------------------------------------------
  417. //    CBreakLinkSourceCommand::CBreakLinkSourceCommand
  418. //---------------------------------------------------------------------------------------
  419.  
  420. CBreakLinkSourceCommand::CBreakLinkSourceCommand(DrawEditor* theEditor, CPublishLink* link):
  421. CCommand(theEditor,  kODTrue, kODTrue, kUndoBreakLinkIndex, kRedoBreakLinkIndex)
  422. {
  423.     fPublishLink = link;
  424.     fHadCommandOutstanding = kODFalse;
  425. }
  426.  
  427.  
  428. //---------------------------------------------------------------------------------------
  429. //    CBreakLinkSourceCommand::~CBreakLinkSourceCommand
  430. //---------------------------------------------------------------------------------------
  431.  
  432. CBreakLinkSourceCommand::~CBreakLinkSourceCommand()
  433. {
  434. }
  435.  
  436. //---------------------------------------------------------------------------------------
  437. //    CBreakLinkSourceCommand::Commit
  438. //---------------------------------------------------------------------------------------
  439.  
  440. void CBreakLinkSourceCommand::Commit(Environment* ev, ODDoneState state)//Override
  441. {
  442.     CCommand::Commit (ev, state);
  443.     
  444.     fPublishLink->SetHasCommandOutstanding(fHadCommandOutstanding);
  445.     
  446.     if (state == kODDone || state == kODRedone && !fHadCommandOutstanding)
  447.     {
  448.         if (fDrawEditor->GetPendingPublish() != fPublishLink && fDrawEditor->GetPendingDragPublish() != fPublishLink)
  449.             delete fPublishLink;
  450.     }
  451. }
  452.  
  453. //---------------------------------------------------------------------------------------
  454. //    CBreakLinkSourceCommand::DoCommand
  455. //---------------------------------------------------------------------------------------
  456.  
  457. void CBreakLinkSourceCommand::DoCommand(Environment* ev)//Override
  458.  
  459. {
  460.     CCommand::DoCommand (ev);
  461.     
  462.     fHadCommandOutstanding = fPublishLink->GetHasCommandOutstanding();
  463.     fPublishLink->SetHasCommandOutstanding(kODTrue);
  464.  
  465.  
  466.     // It doesn't make sense to allow the user to create new destinations for this link
  467.     // after it's been broken.  We don't worry about a pending drag publisher because that
  468.     // expires when the drag is completed. 
  469.     
  470.     if (fDrawEditor->GetPendingPublish() == fPublishLink)
  471.         fDrawEditor->DeletePendingPublish(ev);
  472.  
  473.     fPublishLink->Unpublish(ev);
  474.  
  475. }
  476.  
  477.  
  478. //---------------------------------------------------------------------------------------
  479. //    CBreakLinkSourceCommand::RedoCommand
  480. //---------------------------------------------------------------------------------------
  481.  
  482. void CBreakLinkSourceCommand::RedoCommand(Environment* ev)//Override
  483.  
  484. {
  485.     CCommand::RedoCommand (ev);
  486.  
  487.     // A link spec for this link could have been placed on the clipboard while the break was 'undone'
  488.     if (fDrawEditor->GetPendingPublish() == fPublishLink)
  489.         fDrawEditor->DeletePendingPublish(ev);
  490.  
  491.     fPublishLink->Unpublish(ev);
  492. }
  493.  
  494.  
  495. //---------------------------------------------------------------------------------------
  496. //    CBreakLinkSourceCommand::UndoCommand
  497. //---------------------------------------------------------------------------------------
  498.  
  499. void CBreakLinkSourceCommand::UndoCommand(Environment* ev)//Override
  500.  
  501. {
  502.     CCommand::UndoCommand (ev);
  503.     fPublishLink->Publish(ev);
  504. }
  505.  
  506.  
  507. //=============================================================================
  508. // class CCreateLinkCommand
  509. //=============================================================================
  510.  
  511. //---------------------------------------------------------------------------------------
  512. //    CCreateLinkCommand::CCreateLinkCommand
  513. //---------------------------------------------------------------------------------------
  514.  
  515. CCreateLinkCommand::CCreateLinkCommand(DrawEditor* theEditor, CPublishLink* link):
  516. CCommand(theEditor,  kODTrue, kODTrue, kUndoBreakLinkIndex, kRedoBreakLinkIndex)
  517. {
  518.     fPublishLink = link;
  519. }
  520.  
  521.  
  522. //---------------------------------------------------------------------------------------
  523. //    CCreateLinkCommand::~CCreateLinkCommand
  524. //---------------------------------------------------------------------------------------
  525.  
  526. CCreateLinkCommand::~CCreateLinkCommand()
  527. {
  528. }
  529.  
  530. //---------------------------------------------------------------------------------------
  531. //    CCreateLinkCommand::Commit
  532. //---------------------------------------------------------------------------------------
  533.  
  534. void CCreateLinkCommand::Commit(Environment* ev, ODDoneState state)
  535. {
  536.     CCommand::Commit (ev, state);
  537.     
  538.     if (fPublishLink)
  539.     {
  540.         fPublishLink->SetHasCommandOutstanding(kODFalse);
  541.         
  542.         if (state == kODUndone)
  543.         {
  544.             if (fDrawEditor->GetPendingPublish() != fPublishLink && fDrawEditor->GetPendingDragPublish() != fPublishLink)
  545.                 delete fPublishLink;
  546.         }
  547.     }
  548. }
  549.  
  550.  
  551. //---------------------------------------------------------------------------------------
  552. //    CCreateLinkCommand::DoCommand
  553. //---------------------------------------------------------------------------------------
  554.  
  555. void CCreateLinkCommand::DoCommand(Environment* ev)
  556.  
  557. {
  558.     CCommand::DoCommand (ev);
  559.     
  560.     TRY
  561.         fPublishLink->Publish(ev);
  562.         fPublishLink->ContentUpdated(ev, fDrawEditor->GetSession(ev)->UniqueUpdateID(ev));
  563.     CATCH_ALL
  564.         this->AbortCommand(ev);
  565.         fPublishLink = kODNULL;
  566.     ENDTRY
  567.     
  568.     fPublishLink->SetHasCommandOutstanding(kODTrue);
  569. }
  570.  
  571.  
  572. //---------------------------------------------------------------------------------------
  573. //    CCreateLinkCommand::RedoCommand
  574. //---------------------------------------------------------------------------------------
  575.  
  576. void CCreateLinkCommand::RedoCommand(Environment* ev)//Override
  577.  
  578. {
  579.     CCommand::RedoCommand (ev);
  580.     fPublishLink->Publish(ev);
  581. }
  582.  
  583.  
  584. //---------------------------------------------------------------------------------------
  585. //    CCreateLinkCommand::UndoCommand
  586. //---------------------------------------------------------------------------------------
  587.  
  588. void CCreateLinkCommand::UndoCommand(Environment* ev)//Override
  589.  
  590. {
  591.     CCommand::UndoCommand (ev);
  592.     fPublishLink->Unpublish(ev);
  593. }